import { createApp, toRaw } from 'vue'
import App from './App.vue'
import './assets/css/reset.less'

// pinia的引入
/*
    vue2引入
    import { createPinia, PiniaVuePlugin } from 'pinia'
    Vue.use(PiniaVuePlugin)
    const pinia = createPinia()
*/
import { createPinia, PiniaPluginContext } from 'pinia'     // vue3引入名称  

import Card from './components/Card/index.vue'

import Loading from './components/Loading'

import mitt from 'mitt'
const Mitt = mitt()

const app = createApp(App)

declare module 'vue' {                        // 声明一下vue扩展， ts的声明, 这样就会有提示
    export interface ComponentCustProperties {  
        $Mit: typeof Mitt                      // 扩充$Bus, 在底层声明下 $Bus
    }
}

app.config.globalProperties.$Mit = Mitt        // 全局定义变量要这样写

type Filter = {
    format: <T>(str: T) => string
}
// 进行一下全局声明
declare module '@vue/runtime-core' {
    export interface ComponentCustProperties {
        $filters: Filter
    }
}

// 全局定义filters
app.config.globalProperties.$filters = {
    format<T>(str: T): string {
        return `真·${str}`
    }
}
// 定义变量
app.config.globalProperties.$env = 'env'

//pinia的使用
const store = createPinia()

/** */
// pinia进行持久化封装, 可以封装为另外的的文件
type Options = {
    key?: string
}
const __defaultPiniaKey__: string = 'May'
const setStorage = (key: string, value: any) => {
    localStorage.setItem(key, JSON.stringify(value))
}
const getStorage = (key:string) => {
    return localStorage.getItem(key) ? JSON.parse(localStorage.getItem(key) as string) : {}
}
const piniaPlugin = (options: Options) => {                      // 因为使用的时候，可以接受用户传的参数， 所以进行柯里化的变更
    return (context: PiniaPluginContext) => {
        // console.log(context);
        const { store } = context
        // 获取
        const data = getStorage(`${options?.key ?? __defaultPiniaKey__}-${store.$id}`)
        store.$subscribe(() => {               // 需要监听值的改变
            setStorage(`${options?.key ?? __defaultPiniaKey__}-${store.$id}`, toRaw(store.$state))
        })
        return {
            ...data
        }
    }
}
store.use(piniaPlugin({
    key: 'pinia'
}))
/** */
app.use(store)

app
    .component('Card', Card)
    .use(Loading)                            // 注入
    .mount('#app')


// createApp(App)
//     .component('Card', Card)
//     .mount('#app')
